
#if !defined(AFX_ADPCM_H__362DAEC4_3EFD_44D3_9D5E_7797416B7C4B__INCLUDED_)
#define AFX_ADPCM_H__362DAEC4_3EFD_44D3_9D5E_7797416B7C4B__INCLUDED_

#pragma once

//#include "dsutil.h"
//#include "dxutil.h"
//#include "dxerr9.h"
#include <windows.h>
#include <mmsystem.h>
#include <mmreg.h>
#include <dsound.h>

#define	SIGN_BIT	(0x80)	// Sign bit for a A-law byte.
#define	QUANT_MASK	(0xf)	// Quantization field mask.
#define	NSEGS		(8)		// Number of A-law segments.
#define	SEG_SHIFT	(4)		// Left shift for segment number.
#define	SEG_MASK	(0x70)	// Segment field mask.
#define	BIAS		(0x84)	// Bias for linear code.

class CADPCM
{
protected:
	static const short POWER2[15];
	static const unsigned char _u2a[128];
	static const unsigned char _a2u[128];

	// The following is the definition of the state structure
	// used by the G.721/G.723 encoder and decoder to preserve their internal
	// state between successive calls.  The meanings of the majority
	// of the state structure fields are explained in detail in the
	// CCITT Recommendation G.721.  The field names are essentially indentical
	// to variable names in the bit level description of the coding algorithm
	// included in this Recommendation.
	struct g72x_state
	{
		long yl;		// Locked or steady state step size multiplier. 
		short yu;		// Unlocked or non-steady state step size multiplier. 
		short dms;		// Short term energy estimate. 
		short dml;		// Long term energy estimate. 
		short ap;		// Linear weighting coefficient of 'yl' and 'yu'. 
		
		short a[2];		// Coefficients of pole portion of prediction filter. 
		short b[6];		// Coefficients of zero portion of prediction filter. 
		short pk[2];	// Signs of previous two samples of a partially reconstructed signal.
		short dq[6];	// Previous 6 samples of the quantized difference signal represented in an internal floating point format.
		short sr[2];	// Previous 2 samples of the quantized difference signal represented in an internal floating point format.
		char td;		// delayed tone detect, new in 1988 version

		void Init();
	};

	typedef int (*PFNCODEC)(int, int, g72x_state*);
		
public:
	enum {BIT_16, BIT_24, BIT_32, BIT_40};
	enum {CODING_ALAW, CODING_ULAW, CODING_LINEAR};

	CADPCM();
	virtual ~CADPCM();

	virtual int Run(int i) = 0;
	void Create(int coding_rule);

	unsigned char linear2alaw(int pcm_val);
	int alaw2linear(unsigned char a_val);
	unsigned char linear2ulaw(int pcm_val);
	int ulaw2linear(unsigned char u_val);

protected:
	int quan(int val, short *table, int size);
	int fmult(int an, int srn);
	int predictor_zero();
	int predictor_pole();
	int step_size();
	int quantize(int d, int y, short *table, int size);
	int reconstruct(int sign, int dqln, int y);
	void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez);
	int tandem_adjust_alaw(int sr, int se, int y, int i, int sign, short *qtab);
	int tandem_adjust_ulaw(int sr, int se, int y, int i, int sign, short *qtab);

	int search(int val, short *table, int size);
	unsigned char alaw2ulaw(unsigned char aval);
	unsigned char ulaw2alaw(unsigned char uval);

protected:
	g72x_state	_state;
	int			_coding_rule;
};

class CDecoder16 : public CADPCM
{
	static const short _dqlntab[4];
	static const short _witab[4];
	static const short _fitab[4];
	static const short _qtab[1];

public:
	CDecoder16()
	{}
	virtual ~CDecoder16()
	{}

	virtual int Run(int i);
};

class CDecoder24 : public CADPCM
{
	static const short _dqlntab[8];
	static const short _witab[8];
	static const short _fitab[8];
	static const short _qtab[3];

public:
	CDecoder24()
	{}
	virtual ~CDecoder24()
	{}

	virtual int Run(int i);
};

class CDecoder32 : public CADPCM
{
	static const short _dqlntab[16];
	static const short _witab[16];
	static const short _fitab[16];
	static const short _qtab[7];

public:
	CDecoder32()
	{}
	virtual ~CDecoder32()
	{}

	virtual int Run(int i);
};

class CDecoder40 : public CADPCM
{
	static const short _dqlntab[32];
	static const short _witab[32];
	static const short _fitab[32];
	static const short _qtab[15];

public:
	CDecoder40()
	{}
	virtual ~CDecoder40()
	{}

	virtual int Run(int i);
};

#endif // !defined(AFX_ADPCM_H__362DAEC4_3EFD_44D3_9D5E_7797416B7C4B__INCLUDED_)
